package com.chang.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: changzhenxi
 * @date: 2024年11月07日 09:57
 * @Version: 1.0
 * @description: 两个线程中任意一个执行完毕就可以执行第三个
 */
public class ThreadEitherTest {
    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前01线程启动::::" + Thread.currentThread().getId());
            int aaa = 777;
            System.out.println("当前01线程结束.....");
            return aaa;
        }, executor);


        CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("当前 02 线程启动::::" + Thread.currentThread().getId());
            return "goudan";
        }, executor);

        // runAfterEitherAsync 不感知结果,自身也没有返回值
        // future01.runAfterEitherAsync(future02,()->{System.out.println("线程3开始执行......");},executor);
        // acceptEitherAsync 感知线程执行结果, 自身没有返回值
        // future01.acceptEitherAsync(future02,(res)->{System.out.println("线程3开始执行......"+ res);},executor);
        // applyToEitherAsync 感知线程执行结果,并提供返回值
//        CompletableFuture<Object> completableFuture = future01.applyToEitherAsync(future02, res -> {
//            System.out.println("线程3开始执行......" + res);
//            return res;
//        }, executor);
//        System.out.println("completableFuture.get() = " + completableFuture.get());

        System.out.println("某一线程执行完毕之后就直接执行后续操作" + CompletableFuture.anyOf(future01, future02).get());

        // CompletableFuture.allOf() 检测作为参数的线程执行 作为参数的线程会阻塞 全部线程执行完毕之后再执行下面的方法
        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future01, future02);

        allOfFuture.get();// 此处get方法为阻塞式调用 只有调用get方法才会真正阻塞式等待全部线程执行完毕
        System.out.println("所有方法都已经执行完毕了" + future01.get() + future02.get());


    }
}
